﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace BrowserCollect;

/// <summary>
/// playwright采集脚本工厂
/// </summary>
public class CollectScriptFactory
{
    private readonly HashSet<ICollectScript> _scripts = new HashSet<ICollectScript>();

    private static CollectScriptFactory? _instance;
    private DefaultCollectScript _defaultCollectScript = new DefaultCollectScript();

    public static CollectScriptFactory Instance => _instance ??= new CollectScriptFactory();
    
    /// <summary>
    /// 注册一个采集脚本
    /// </summary>
    /// <param name="script"></param>
    public void Register(ICollectScript script)
    {
        _scripts.Add(script);
    }

    /// <summary>
    /// 注册程序集中的所有采集脚本
    /// </summary>
    /// <param name="assemblies"></param>
    public void Register(params Assembly[] assemblies)
    {
        foreach (var assembly in assemblies)
        {
            foreach (var type in assembly.ExportedTypes.Where(t => !t.IsInterface && !t.IsAbstract 
                         && typeof(ICollectScript).IsAssignableFrom(t) && t != typeof(DefaultCollectScript)))
            {
                _scripts.Add((ICollectScript)Activator.CreateInstance(type));
            }
        }
    }
    /// <summary>
    /// 手动注册新加入的脚本
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public void Register<T>() where T : ICollectScript
    {
        _scripts.Add((ICollectScript)Activator.CreateInstance(typeof(T)));
    }

    /// <summary>
    /// 获取可适用于该url的采集脚本，如无匹配则返回默认脚本
    /// </summary>
    /// <param name="url">url</param>
    /// <returns></returns>
    public ICollectScript GetMatchedScript(string url)
    {
        return _scripts.FirstOrDefault(s => s.IsMatch(url)) ?? _defaultCollectScript;
    }
}